package game.userinteraction;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.swing.KeyStroke;


/**
 * Will record key strokes from a user and buffer them based
 * on the game's frame rate. Will then dispense those key strokes
 * to any IControllable Objects that can be controlled by
 * user input. Any Object that shares this behavior (e.g. a Sprite
 * that can jump if the user hits Spacebar or a Level that can reset
 * if the user hits r) should register itself with this Object.
 * 
 * @author Paul
 * @author rwb10
 * 
 */
public class UserInputHandler extends KeyAdapter implements IUpdatable {

    private Set<KeyStroke> myPresses;

    private Collection<IControllable> myListeners;

    /**
     * Creates a new UserInputHandler that will dispense key press
     * information to the Objects specified as a parameter.
     * 
     * @param listeners The Objects who will be sent key press info.
     */
    public UserInputHandler(Collection<IControllable> listeners) {
        myListeners = listeners;
        myPresses = new HashSet<KeyStroke>();

    }

    /**
     * Creates an empty UserInputHandler.
     */
    public UserInputHandler() {
        myListeners = new ArrayList<IControllable>();
        myPresses = new HashSet<KeyStroke>();

    }

    /**
     * Adds an Object that can be influenced by user input to
     * this UserInputHandler.
     * 
     * @param userControllable The Object that will now be
     *        given key press information through its react() method.
     */
    public void add(IControllable userControllable) {
        myListeners.add(userControllable);
    }

    /**
     * Removes an Object from the UserInputHandler if it is
     * currently registered.
     * 
     * @param userControllable The Object to remove.
     */
    public void remove(IControllable userControllable) {
        myListeners.remove(userControllable);
    }

    @Override
    public void keyPressed(KeyEvent e) {

        myPresses.add(KeyStroke.getKeyStrokeForEvent(e));
        // System.out.println("keypressed!" + myPresses.size());

    }

    @Override
    public void keyReleased(KeyEvent e) {
        myPresses.remove(KeyStroke.getKeyStrokeForEvent(e));
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    /**
     * Sends an unmodifiable set of buffered key presses
     * to any listeners.
     */
    @Override
    public void update() {
        for (IControllable listener : myListeners) {
            listener.react(Collections.unmodifiableSet(myPresses));
        }
        myPresses.clear();

    }

}
